package cn.kpt.biz.controller;

import cn.kpt.beans.dto.Dto;
import cn.kpt.beans.pojo.*;
import cn.kpt.beans.vo.order.*;
import cn.kpt.biz.service.HotelOrderService;
import cn.kpt.biz.service.HotelRoomService;
import cn.kpt.biz.service.HotelService;
import cn.kpt.biz.service.ItripOrderLinkUserService;
import cn.kpt.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @version 1.0
 * @ClassName HotelOrderController
 * @Description TODO
 * @Author kangpengtao
 * @Date 2019/10/23 10:51
 */
@Api(value = "api")
@RestController
@RequestMapping("/api/hotelorder")
public class HotelOrderController {
    @Resource
    private HotelOrderService hotelOrderService;
    @Resource
    private ValidationToken validationToken;
    @Resource
    private HotelRoomService hotelRoomService;
    @Resource
    private HotelService hotelService;
    @Resource
    private ItripOrderLinkUserService itripOrderLinkUserService;

    @ApiOperation(value = "根据订单ID获取订单信息", httpMethod = "GET",
            protocols = "HTTP", produces = "application/json",
            response = Dto.class, notes = "根据订单ID获取订单信息" +
            "<p>成功：success = ‘true’ | 失败：success = ‘false’ 并返回错误码，如下：</p>" +
            "<p>错误码：</p>" +
            "<p>100533 : 没有查询到相应订单 </p>" +
            "<p>100534 : 系统异常 </p>")
    @RequestMapping(value = "/queryOrderById/{orderId}", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    public Dto<Object> queryOrderById(@ApiParam(required = true, name = "orderId", value = "订单ID") @PathVariable Long orderId, @RequestHeader String token) {
        ItripModifyHotelOrderVO itripModifyHotelOrderVO = null;
        try {
            ItripUser currentUser = validationToken.getCurrentUser("token:" + token);

            if(EmptyUtils.isEmpty(currentUser)){
                return DtoUtil.returnFail("token失效，请重登录", "100000");
            }
            ItripHotelOrder order = hotelOrderService.getById(orderId);
            if (EmptyUtils.isEmpty(order)) {
                return DtoUtil.returnFail("100533", "没有查询到相应订单");
            }
            itripModifyHotelOrderVO = new ItripModifyHotelOrderVO();
            BeanUtils.copyProperties(order, itripModifyHotelOrderVO);
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("orderId", order.getId());
            List<ItripOrderLinkUserVo> itripOrderLinkUserList = itripOrderLinkUserService.getItripOrderLinkUserListByMap(param);
            itripModifyHotelOrderVO.setItripOrderLinkUserList(itripOrderLinkUserList);
            return DtoUtil.returnSuccess("获取订单成功", itripModifyHotelOrderVO);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("系统异常", "100534");
        }
    }
    /**
     * 选择支付页面-查询订单房间信息
     * @param orderId
     * @return
     */
    @ApiOperation(value = "根据订单ID查看个人订单详情-房型相关信息", httpMethod = "GET",
            protocols = "HTTP", produces = "application/json",
            response = Dto.class, notes = "根据订单ID查看个人订单详情-房型相关信息" +
            "<p>成功：success = ‘true’ | 失败：success = ‘false’ 并返回错误码，如下：</p>" +
            "<p>错误码：</p>" +
            "<p>100529 : 请传递参数：orderId </p>" +
            "<p>100530 : 没有相关订单房型信息 </p>" +
            "<p>100531 : 获取个人订单房型信息错误 </p>" +
            "<p>支持支付类型(roomPayType)：{\"1\":\"在线付\",\"2\":\"线下付\",\"3\":\"不限\"}</p>" +
            "<p>100000 : token失效，请重登录 </p>")
    @RequestMapping(value = "/getpersonalorderroominfo/{orderId}",method = RequestMethod.GET)
    public Dto doGetPersonalOrderRoomInfo(@PathVariable Long orderId){
        try {
            ItripHotelOrder itripHotelOrder = hotelOrderService.getById(orderId);
            // 订单信息封装完毕
            ItripPersonalOrderRoomVO vo = new ItripPersonalOrderRoomVO();
            BeanUtils.copyProperties(itripHotelOrder,vo);
            vo.setRoomPayType(itripHotelOrder.getPayType());
            // 酒店信息封装
            ItripHotel itripHotel = hotelService.queryHotelById(itripHotelOrder.getHotelId());
            BeanUtils.copyProperties(itripHotel,vo);
            // 房间信息封装
            ItripHotelRoom itripHotelRoom = hotelRoomService.getRoomById(itripHotelOrder.getRoomId());
            BeanUtils.copyProperties(itripHotelRoom,vo);
            return DtoUtil.returnDataSuccess(vo);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("查询订单信息失败！",ErrorCode.BIZ_UNKNOWN);
        }
    }
    /**
     * 选择支付页面-查询订单详情
     * @param orderId
     * @return
     */
    @ApiOperation(value = "根据订单ID查看个人订单详情", httpMethod = "GET",
            protocols = "HTTP", produces = "application/json",
            response = Dto.class, notes = "根据订单ID查看个人订单详情" +
            "<p>订单状态(orderStatus)（0：待支付 1:已取消 2:支付成功 3:已消费 4：已点评）：</p>" +
            "<p>订单流程：</p>" +
            "<p>订单状态(0：待支付 2:支付成功 3:已消费 4:已点评)的流程：{\"1\":\"订单提交\",\"2\":\"订单支付\",\"3\":\"支付成功\",\"4\":\"入住\",\"5\":\"订单点评\",\"6\":\"订单完成\"}</p>" +
            "<p>订单状态(1:已取消)的流程：{\"1\":\"订单提交\",\"2\":\"订单支付\",\"3\":\"订单取消\"}</p>" +
            "<p>支持支付类型(roomPayType)：{\"1\":\"在线付\",\"2\":\"线下付\",\"3\":\"不限\"}</p>" +
            "<p>成功：success = ‘true’ | 失败：success = ‘false’ 并返回错误码，如下：</p>" +
            "<p>错误码：</p>" +
            "<p>100525 : 请传递参数：orderId </p>" +
            "<p>100526 : 没有相关订单信息 </p>" +
            "<p>100527 : 获取个人订单信息错误 </p>" +
            "<p>100000 : token失效，请重登录 </p>")
    @RequestMapping(value = "/getpersonalorderinfo/{orderId}",method = RequestMethod.GET)
    public Dto doGetPersonalOrderInfo(@PathVariable Long orderId){
        try {
            ItripHotelOrder itripHotelOrder = hotelOrderService.getById(orderId);
            ItripPersonalHotelOrderVO vo = new ItripPersonalHotelOrderVO();
            BeanUtils.copyProperties(itripHotelOrder,vo);

            ItripHotelRoom hotelRoom = hotelRoomService.getRoomById(itripHotelOrder.getRoomId());
            vo.setRoomPayType(hotelRoom.getPayType());
            return DtoUtil.returnDataSuccess(vo);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("查询订单信息失败！",ErrorCode.BIZ_UNKNOWN);
        }
    }
    /**
     * 订单页面-生成订单
     * @param vo
     * @param token
     * @return
     */
    @ApiOperation(value = "生成订单", httpMethod = "POST",
            protocols = "HTTP", produces = "application/json",
            response = Dto.class, notes = "生成订单" +
            "<p>成功：success = ‘true’ | 失败：success = ‘false’ 并返回错误码，如下：</p>" +
            "<p>错误码：</p>" +
            "<p>100505 : 生成订单失败 </p>" +
            "<p>100506 : 不能提交空，请填写订单信息 </p>" +
            "<p>100507 : 库存不足 </p>" +
            "<p>100000 : token失效，请重登录</p>")
    @RequestMapping(value = "/addhotelorder",method = RequestMethod.POST)
    public Dto doAddHotelOrder(@RequestBody ItripAddHotelOrderVO vo, @RequestHeader String token){
        try {
            // 表单验证
            if(EmptyUtils.isEmpty(vo.getHotelId())
                    || EmptyUtils.isEmpty(vo.getRoomId())
                    || EmptyUtils.isEmpty(vo.getCount())
                    || EmptyUtils.isEmpty(vo.getCheckInDate())
                    || EmptyUtils.isEmpty(vo.getCheckOutDate())){
                return DtoUtil.returnFail("参数有误！",ErrorCode.BIZ_PARAMETER_ERROR);
            }

            if(vo.getCheckOutDate().getTime() < new Date().getTime() || vo.getCheckInDate().getTime() > vo.getCheckOutDate().getTime()){
                return DtoUtil.returnFail("入住时间和退房时间非法！",ErrorCode.BIZ_PARAMETER_ERROR);
            }

            List<Date> betweenDates = DateUtil.getBetweenDates(vo.getCheckInDate(), vo.getCheckOutDate());
            // 检查库存
            if(!hotelRoomService.checkRoomStock(vo.getRoomId(),vo.getCount(),betweenDates)){
                return DtoUtil.returnFail("来晚一步！库存不足！",ErrorCode.BIZ_RESULT_ERROR);
            }
            // 获取当前用户
            ItripUser currentUser = validationToken.getCurrentUser("token:" + token);

            // 保存订单信息（可以用BeanUtil来实现快速复制）
            ItripHotelOrder itripHotelOrder = new ItripHotelOrder();
            BeanUtils.copyProperties(vo,itripHotelOrder);

            itripHotelOrder.setBookingDays(betweenDates.size());
            ItripHotelRoom hotelRoom = hotelRoomService.getRoomById(vo.getRoomId());
            itripHotelOrder.setPayAmount(hotelRoom.getRoomPrice(),vo.getCount(),betweenDates.size()); // 后台计算
            itripHotelOrder.setOrderNo(OrderUtil.genOrderNo(hotelRoom.getId())); // 后台生成
            // 预定类型
            int bookType = 2;
            if(token.startsWith("PC-")){
                bookType = 0;
            }else if(token.startsWith("MOBILE-")){
                bookType = 1;
            }
            itripHotelOrder.setBookType(bookType);
            itripHotelOrder.setOrderType(1); // 酒店产品
            itripHotelOrder.setOrderStatus(0); // 预定
            itripHotelOrder.setUserId(currentUser.getId());
            itripHotelOrder.setCreatedBy(currentUser.getId());
            itripHotelOrder.setCreationDate(new Date());
            // 联系人
            StringBuffer linkUserName = new StringBuffer();
            for (ItripUserLinkUser itripUserLinkUser : vo.getLinkUser()) {
                linkUserName.append(itripUserLinkUser.getLinkUserName()+",");
            }
            itripHotelOrder.setLinkUserName(linkUserName.toString());

            hotelOrderService.addHotelOrder(itripHotelOrder);

            Map<String, Object> map = new HashMap<>();
            map.put("orderNo",itripHotelOrder.getOrderNo());
            map.put("id",itripHotelOrder.getId());
            return DtoUtil.returnDataSuccess(map);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("生成订单失败！",ErrorCode.BIZ_UNKNOWN);
        }
    }
    /**
     * 订单页面-查询前置信息
     * @param vo
     * @return
     */
    @ApiOperation(value = "生成订单前,获取预订信息", httpMethod = "POST",
            protocols = "HTTP", produces = "application/json",
            response = Dto.class, notes = "生成订单前,获取预订信息" +
            "<p>成功：success = ‘true’ | 失败：success = ‘false’ 并返回错误码，如下：</p>" +
            "<p>错误码：</p>" +
            "<p>100000 : token失效，请重登录 </p>" +
            "<p>100510 : hotelId不能为空</p>" +
            "<p>100511 : roomId不能为空</p>" +
            "<p>100512 : 暂时无房</p>" +
            "<p>100513 : 系统异常</p>")
    @RequestMapping(value = "/getpreorderinfo",method = RequestMethod.POST)
    public Dto getpreorderinfo(@RequestBody PreAddOrderVO vo){
        try {
            // 表单验证
            if(EmptyUtils.isEmpty(vo.getCheckInDate()) || EmptyUtils.isEmpty(vo.getCheckOutDate())){
                return DtoUtil.returnFail("入住和退房时间不能为空！", ErrorCode.BIZ_PARAMETER_ERROR);
            }
            if(vo.getCheckInDate().getTime() > vo.getCheckOutDate().getTime()){
                return DtoUtil.returnFail("入住时间不能晚于退房时间！",ErrorCode.BIZ_PARAMETER_ERROR);
            }
            hotelOrderService.getPreOrderInfo(vo);
            return DtoUtil.returnDataSuccess(vo);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("查询前置信息失败！", ErrorCode.BIZ_UNKNOWN);
        }
    }
}
